/********************************************************************************
*	Programmer:		Brandon Shouse
*	Class:			CS362-400
*	Project:		Assignment 4 - randomtestadventurer.c
*
*	Description: 	Random tester that generates 2000 random intstances to test the adventurer
*					card effect.
*
**********************************************************************************/

#include <string.h> 
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include <stdlib.h>
 
#include "rngs.h"
#include "dominion.h" 
#include "dominion_helpers.h"

int checkCard(struct gameState *state);

int main() {
 
        int i;
		int j;
		int k;
		int randNum; 
        struct gameState state;
		int temp1;
 
        printf("Random testing for adventurer card...\n");
        
		SelectStream(2);
        PutSeed(3);
 
        //Sets up and runs test 2000 times with different gamestates
        for (j = 0; j < 2000; j++) 
		{
				temp1 = j + 1;
				printf("Test iteration: %d\n", temp1);
                for (i = 0; i < sizeof(struct gameState); i++) 
				{
                        ((char*) &state)[i] = floor(Random() * 256);
                }
 
                state.numPlayers = 2 + floor(Random() * (MAX_PLAYERS - 2));
 
                for (i = 0; i <= state.numPlayers; i++) 
				{
                        state.deckCount[i] = floor(Random() * MAX_DECK);
                        state.discardCount[i] = floor(Random() * MAX_DECK);
 
                        state.handCount[i] = floor(Random() * MAX_HAND);
 
                        for (k = 0; k < MAX_HAND; k++) 
						{
                                state.hand[i][k] = floor(Random() * 26);
                                state.discard[i][k] = floor(Random() * 26);
                                state.deck[i][k] = floor(Random() * 26);
 
                        }
 
                }
 
                state.playedCardCount = floor(Random() * MAX_DECK);
                state.whoseTurn = floor(Random() * state.numPlayers);
                randNum = floor(Random() * 100);
 
                if (randNum <= 1)
				{
                        state.handCount[state.whoseTurn] = 1;
                }
				if (checkCard(&state) != 0)
				{
                        break;
				}
				else
					printf("... Adventurer card effect passed all tests.\n");
        }
 
        
        exit(0);
 
}
 
//Tests adventurer card for specific card effect
int checkCard(struct gameState *state) 
{
        struct gameState preState; 
        memcpy(&preState, state, sizeof(struct gameState));
		
        int r, randNum, handPos, cardDrawn;
        int drawntreasure = 0;
        int temphand[MAX_HAND];
        int z = 0;
        int *bonus = 0;
        long *x = malloc(sizeof(long));

        randNum = floor(Random() * 10);
 
        if (randNum <= 1)
		{
                handPos = state->handCount[state->whoseTurn] - 1;
		}
        else
		{
                handPos = floor(Random() * state->handCount[state->whoseTurn]);
		}

        GetSeed(x); 
        r = cardEffect(adventurer, 0, 0, 0, state, handPos, bonus);
        PutSeed(*x);
 
        while (drawntreasure < 2) 
		{
                if (preState.deckCount[preState.whoseTurn] < 1) 
				{ //if the deck is empty we need to shuffle discard and add to deck
 
                        shuffle(preState.whoseTurn, &preState);
 
                }
 
                drawCard(preState.whoseTurn, &preState);
                cardDrawn = preState.hand[preState.whoseTurn][preState.handCount[preState.whoseTurn] - 1]; //top card of hand is most recently drawn card.
                if (cardDrawn == copper || cardDrawn == silver || cardDrawn == gold)
				{
                        drawntreasure++;
				}
                else 
				{
                        temphand[z] = cardDrawn;
                        preState.handCount[preState.whoseTurn]--; //this should just remove the top card (the most recently drawn one).
                        z++;
                }
 
        }
 
        while (z - 1 >= 0) 
		{
                preState.discard[preState.whoseTurn][preState.discardCount[preState.whoseTurn]++] =
					temphand[z - 1]; // discard all cards in play that have been draw 
                z = z - 1;
 
        }
 
        if (r != 0) 
		{
                printf("ERROR: CardEffect function returned non-zero value!!!\n");
                return -1;
        }
 
        if (memcmp(&preState, state, sizeof(struct gameState)) != 0) {
                printf("ERROR: CardEffect did not perform correctly!!!\n");
                return -1;
        }
        return 0;
}
 
